#include "read_only_env.h"

namespace leveldb {

  // Create an object that sequentially reads the file with the specified name.
  // On success, stores a pointer to the new file in *result and returns OK.
  // On failure stores nullptr in *result and returns non-OK.  If the file does
  // not exist, returns a non-OK status.  Implementations should return a
  // NotFound status when the file does not exist.
  //
  // The returned file will only be accessed by one thread at a time.
  Status ReadOnlyEnv::NewSequentialFile(const std::string& fname,
                                   SequentialFile** result) {
    return defaultEnv_->NewSequentialFile(fname, result);
  }

  // Create an object supporting random-access reads from the file with the
  // specified name.  On success, stores a pointer to the new file in
  // *result and returns OK.  On failure stores nullptr in *result and
  // returns non-OK.  If the file does not exist, returns a non-OK
  // status.  Implementations should return a NotFound status when the file does
  // not exist.
  //
  // The returned file may be concurrently accessed by multiple threads.
  Status ReadOnlyEnv::NewRandomAccessFile(const std::string& fname,
                                     RandomAccessFile** result) {
    return defaultEnv_->NewRandomAccessFile(fname, result);
  }

  // Create an object that writes to a new file with the specified
  // name.  Deletes any existing file with the same name and creates a
  // new file.  On success, stores a pointer to the new file in
  // *result and returns OK.  On failure stores nullptr in *result and
  // returns non-OK.
  //
  // The returned file will only be accessed by one thread at a time.
  Status ReadOnlyEnv::NewWritableFile(const std::string& fname,
                                 WritableFile** result) {
     // Prevent creation of new files (including the LOCK file)
    return leveldb::Status::IOError(fname, "Read-only file system");
  }

  // Create an object that either appends to an existing file, or
  // writes to a new file (if the file does not exist to begin with).
  // On success, stores a pointer to the new file in *result and
  // returns OK.  On failure stores nullptr in *result and returns
  // non-OK.
  //
  // The returned file will only be accessed by one thread at a time.
  //
  // May return an IsNotSupportedError error if this Env does
  // not allow appending to an existing file.  Users of Env (including
  // the leveldb implementation) must be prepared to deal with
  // an Env that does not support appending.
  Status ReadOnlyEnv::NewAppendableFile(const std::string& fname,
                                   WritableFile** result) {
    return defaultEnv_->NewAppendableFile(fname, result);
  }

  // Returns true iff the named file exists.
  bool ReadOnlyEnv::FileExists(const std::string& fname) {
    return defaultEnv_->FileExists(fname);
  }

  // Store in *result the names of the children of the specified directory.
  // The names are relative to "dir".
  // Original contents of *results are dropped.
  Status ReadOnlyEnv::GetChildren(const std::string& dir,
                             std::vector<std::string>* result) {
    return defaultEnv_->GetChildren(dir, result);
  }
  // Delete the named file.
  //
  // The default implementation calls DeleteFile, to support legacy Env
  // implementations. Updated Env implementations must RemoveFile and
  // ignore the existence of DeleteFile. Updated code calling into the Env API
  // must call RemoveFile instead of DeleteFile.
  //
  // A future release will remove DeleteDir and the default implementation of
  // RemoveDir.
  Status ReadOnlyEnv::RemoveFile(const std::string& fname) {
    return defaultEnv_->RemoveFile(fname);
  }

  // DEPRECATED: Modern Env implementations should RemoveFile instead.
  //
  // The default implementation calls RemoveFile, to support legacy Env user
  // code that calls this method on modern Env implementations. Modern Env user
  // code should call RemoveFile.
  //
  // A future release will remove this method.
  Status ReadOnlyEnv::DeleteFile(const std::string& fname) {
    return defaultEnv_->DeleteFile(fname);
  }

  // Create the specified directory.
  Status ReadOnlyEnv::CreateDir(const std::string& dirname) {
    return defaultEnv_->CreateDir(dirname);
  }

  // Delete the specified directory.
  //
  // The default implementation calls DeleteDir, to support legacy Env
  // implementations. Updated Env implementations must RemoveDir and
  // ignore the existence of DeleteDir. Modern code calling into the Env API
  // must call RemoveDir instead of DeleteDir.
  //
  // A future release will remove DeleteDir and the default implementation of
  // RemoveDir.
  Status ReadOnlyEnv::RemoveDir(const std::string& dirname) {
    return defaultEnv_->RemoveDir(dirname);
  }

  // DEPRECATED: Modern Env implementations should RemoveDir instead.
  //
  // The default implementation calls RemoveDir, to support legacy Env user
  // code that calls this method on modern Env implementations. Modern Env user
  // code should call RemoveDir.
  //
  // A future release will remove this method.
  Status ReadOnlyEnv::DeleteDir(const std::string& dirname) {
    return defaultEnv_->DeleteDir(dirname);
  }

  // Store the size of fname in *file_size.
  Status ReadOnlyEnv::GetFileSize(const std::string& fname, uint64_t* file_size) {
    return defaultEnv_->GetFileSize(fname, file_size);
  }

  // Rename file src to target.
  Status ReadOnlyEnv::RenameFile(const std::string& src,
                            const std::string& target) {
    return defaultEnv_->RenameFile(src, target);
  }


  // Lock the specified file.  Used to prevent concurrent access to
  // the same db by multiple processes.  On failure, stores nullptr in
  // *lock and returns non-OK.
  //
  // On success, stores a pointer to the object that represents the
  // acquired lock in *lock and returns OK.  The caller should call
  // UnlockFile(*lock) to release the lock.  If the process exits,
  // the lock will be automatically released.
  //
  // If somebody else already holds the lock, finishes immediately
  // with a failure.  I.e., this call does not wait for existing locks
  // to go away.
  //
  // May create the named file if it does not already exist.
  Status ReadOnlyEnv::LockFile(const std::string& fname, FileLock** lock) {
    return defaultEnv_->LockFile(fname, lock);
  }

  // Release the lock acquired by a previous successful call to LockFile.
  // REQUIRES: lock was returned by a successful LockFile() call
  // REQUIRES: lock has not already been unlocked.
  Status ReadOnlyEnv::UnlockFile(FileLock* lock) {
    return defaultEnv_->UnlockFile(lock);
  }

  // Arrange to run "(*function)(arg)" once in a background thread.
  //
  // "function" may run in an unspecified thread.  Multiple functions
  // added to the same Env may run concurrently in different threads.
  // I.e., the caller may not assume that background work items are
  // serialized.
  void ReadOnlyEnv::Schedule(void (*function)(void* arg), void* arg) {
    return defaultEnv_->Schedule(function, arg);
  }

  // Start a new thread, invoking "function(arg)" within the new thread.
  // When "function(arg)" returns, the thread will be destroyed.
  void ReadOnlyEnv::StartThread(void (*function)(void* arg), void* arg) {
    return defaultEnv_->StartThread(function, arg);
  }


  // *path is set to a temporary directory that can be used for testing. It may
  // or may not have just been created. The directory may or may not differ
  // between runs of the same process, but subsequent calls will return the
  // same directory.
  Status ReadOnlyEnv::GetTestDirectory(std::string* path) {
    return defaultEnv_->GetTestDirectory(path);
  }

  // Create and return a log file for storing informational messages.
  Status ReadOnlyEnv::NewLogger(const std::string& fname, Logger** result) {
    return defaultEnv_->NewLogger(fname, result);
  }


  // Returns the number of micro-seconds since some fixed point in time. Only
  // useful for computing deltas of time.
  uint64_t ReadOnlyEnv::NowMicros() {
    return defaultEnv_->NowMicros();
  }

  // Sleep/delay the thread for the prescribed number of micro-seconds.
  void ReadOnlyEnv::SleepForMicroseconds(int micros) {
    return defaultEnv_->SleepForMicroseconds(micros);
  }
} // namespace leveldb
